package com.syn.synold4s.vm;

import android.app.Application;
import android.text.TextUtils;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.lifecycle.MutableLiveData;

import com.gaoyi.basemodule.apiresult.ApiResultData;
import com.gaoyi.basemodule.baseCallback.OnResultListener;
import com.gaoyi.basemodule.baseUtil.LanguageUtils;
import com.gaoyi.basemodule.baseUtil.OKHttpUtil;
import com.gaoyi.basemodule.baseUtil.SPUtil;
import com.gaoyi.basemodule.baseUtil.ThreadManager;
import com.gaoyi.basemodule.baseUtil.ToastUtil;
import com.gaoyi.basemodule.basebean.LoginDto;
import com.gaoyi.basemodule.basebean.ProjectDto;
import com.gaoyi.basemodule.baseconstant.ApiStatus;
import com.gaoyi.basemodule.baseconstant.SPName;
import com.gaoyi.basemodule.basevm.BaseViewModel;
import com.google.gson.reflect.TypeToken;
import com.syn.synold4s.R;
import com.syn.synold4s.bean.dto.AddressDto;
import com.syn.synold4s.bean.dto.AiDto;
import com.syn.synold4s.bean.dto.AlertDto;
import com.syn.synold4s.bean.dto.AlertEventDto;
import com.syn.synold4s.bean.dto.AssetDto;
import com.syn.synold4s.bean.dto.CctvDto;
import com.syn.synold4s.bean.dto.GasMonitoringDto;
import com.syn.synold4s.bean.dto.GoogleMapBean;
import com.syn.synold4s.bean.dto.HelmetDto;
import com.syn.synold4s.bean.dto.LockDto;
import com.syn.synold4s.bean.dto.MainDto;
import com.syn.synold4s.bean.dto.MapAllDeviceDto;
import com.syn.synold4s.bean.dto.PermitToWorkDto;
import com.syn.synold4s.bean.dto.SafetyTrainingDto;
import com.syn.synold4s.bean.dto.ShortDto;
import com.syn.synold4s.bean.dto.UnSafeActEventDto;
import com.syn.synold4s.bean.dto.WatchListDto;
import com.syn.synold4s.bean.dto.WeatherDto;
import com.syn.synold4s.constants.TagCode;
import com.syn.synold4s.repository.ComboRepository;
import com.syn.synold4s.repository.GoogleMapRepository;
import com.syn.synold4s.repository.MainRepository;

import java.util.ArrayList;
import java.util.List;

public class MainViewModel extends BaseViewModel {

    MutableLiveData<List<PermitToWorkDto>> mPermitToWork;
    MutableLiveData<List<SafetyTrainingDto>> mVrs;
    MutableLiveData<List<WeatherDto>> mWeather;
    MutableLiveData<List<GasMonitoringDto>> mGasMonitoring;
    MutableLiveData<List<WatchListDto>> mWatch;
    MutableLiveData<List<LockDto>> mLock;
    MutableLiveData<List<AlertDto>> mAlert;
    MutableLiveData<List<UnSafeActEventDto>> mUnSafeAct;
    MutableLiveData<List<ProjectDto>> mProject;
    MutableLiveData<LoginDto> mTagByProj;
    MutableLiveData<List<ShortDto>> mAlertTypes;
    MutableLiveData<AssetDto> mAsset;
    MutableLiveData<AiDto> mAi;
    MutableLiveData<HelmetDto> mHelmet;
    MutableLiveData<List<MapAllDeviceDto>> mMapDevice;
    List<String> mTagCodes = new ArrayList<>();
    final MainRepository mRepository;
    final ComboRepository mComboRepository;
    final GoogleMapRepository mMapRepository;
    String mGasKeyWord = "";
    String mAlertKeyWord = "";
    MutableLiveData<Boolean> mStatusPTW;
    MutableLiveData<Boolean> mStatusVrs;
    MutableLiveData<Boolean> mStatusGas;
    MutableLiveData<Boolean> mStatusWatch;
    MutableLiveData<Boolean> mStatusLock;
    MutableLiveData<Boolean> mStatusAlert;
    MutableLiveData<Boolean> mStatusUnSafeAct;
    MutableLiveData<Boolean> mStatusAsset;
    MutableLiveData<Boolean> mStatusAi;
    MutableLiveData<Boolean> mStatusHelmet;
    private MutableLiveData<MapAllDeviceDto> mapDeviceDetails;
    private MutableLiveData<Integer> mRefreshResultCode;
    private MutableLiveData<Integer> mAlertResultCode;
    private MutableLiveData<AddressDto> address;
    private MutableLiveData<MainDto> allMainDto;
    private MutableLiveData<List<AlertEventDto>> deviceInfo;

    public MainViewModel(@NonNull Application application) {
        super(application);
        mRepository = new MainRepository();
        mComboRepository = new ComboRepository();
        mMapRepository = new GoogleMapRepository();
    }

    public MutableLiveData<Integer> getRefreshResultCode() {
        if (mRefreshResultCode == null) {
            mRefreshResultCode = new MutableLiveData<>();
        }
        return mRefreshResultCode;
    }

    public MutableLiveData<Integer> getAlertResultCode() {
        if (mAlertResultCode == null) {
            mAlertResultCode = new MutableLiveData<>();
        }
        return mAlertResultCode;
    }

    public MutableLiveData<LoginDto> getTagByProj() {
        if (mTagByProj == null) {
            mTagByProj = new MutableLiveData<>();
        }
        return mTagByProj;
    }

    public void setGasKeyWord(String gasKeyWord) {
        this.mGasKeyWord = gasKeyWord;
    }

    public void setAlertKeyWord(String alertKeyWord) {
        this.mAlertKeyWord = alertKeyWord;
    }

    public void setTagCodes(List<String> data) {
        mTagCodes.clear();
        mTagCodes.addAll(data);
    }

    public MutableLiveData<AddressDto> getAddress() {
        if (address == null) {
            address = new MutableLiveData<>();
        }
        return address;
    }

    public MutableLiveData<List<PermitToWorkDto>> getPermitToWork() {
        if (mPermitToWork == null) {
            mPermitToWork = new MutableLiveData<>();
        }
        return mPermitToWork;
    }

    public MutableLiveData<Boolean> getStatusPTW() {
        if (mStatusPTW == null) {
            mStatusPTW = new MutableLiveData<>();
        }
        return mStatusPTW;
    }

    public MutableLiveData<Boolean> getStatusVrs() {
        if (mStatusVrs == null) {
            mStatusVrs = new MutableLiveData<>();
        }
        return mStatusVrs;
    }

    public MutableLiveData<Boolean> getStatusGas() {
        if (mStatusGas == null) {
            mStatusGas = new MutableLiveData<>();
        }
        return mStatusGas;
    }

    public MutableLiveData<Boolean> getStatusWatch() {
        if (mStatusWatch == null) {
            mStatusWatch = new MutableLiveData<>();
        }
        return mStatusWatch;
    }

    public MutableLiveData<Boolean> getStatusLock() {
        if (mStatusLock == null) {
            mStatusLock = new MutableLiveData<>();
        }
        return mStatusLock;
    }

    public MutableLiveData<Boolean> getStatusAlert() {
        if (mStatusAlert == null) {
            mStatusAlert = new MutableLiveData<>();
        }
        return mStatusAlert;
    }

    public MutableLiveData<Boolean> getStatusUnSafeAct() {
        if (mStatusUnSafeAct == null) {
            mStatusUnSafeAct = new MutableLiveData<>();
        }
        return mStatusUnSafeAct;
    }

    public MutableLiveData<Boolean> getStatusAsset() {
        if (mStatusAsset == null) {
            mStatusAsset = new MutableLiveData<>();
        }
        return mStatusAsset;
    }

    public MutableLiveData<Boolean> getStatusAi() {
        if (mStatusAi == null) {
            mStatusAi = new MutableLiveData<>();
        }
        return mStatusAi;
    }

    public MutableLiveData<Boolean> getStatusHelmet() {
        if (mStatusHelmet == null) {
            mStatusHelmet = new MutableLiveData<>();
        }
        return mStatusHelmet;
    }

    public MutableLiveData<List<MapAllDeviceDto>> getMapAllDevice() {
        if (mMapDevice == null) {
            mMapDevice = new MutableLiveData<>();
            mMapDevice.setValue(new ArrayList<>());
        }
        return mMapDevice;
    }

    public MutableLiveData<List<SafetyTrainingDto>> getVrs() {
        if (mVrs == null) {
            mVrs = new MutableLiveData<>();
        }
        return mVrs;
    }

    public MutableLiveData<List<WeatherDto>> getWeather() {
        if (mWeather == null) {
            mWeather = new MutableLiveData<>();
        }
        return mWeather;
    }

    public MutableLiveData<List<AlertEventDto>> getDeviceInfoResult(){
        if (deviceInfo == null){
            deviceInfo = new MutableLiveData<>();
        }
        return deviceInfo;
    }

    public MutableLiveData<List<GasMonitoringDto>> getGasMonitoring() {
        if (mGasMonitoring == null) {
            mGasMonitoring = new MutableLiveData<>();
            mGasMonitoring.setValue(new ArrayList<>());
        }
        return mGasMonitoring;
    }

    public MutableLiveData<List<WatchListDto>> getWatch() {
        if (mWatch == null) {
            mWatch = new MutableLiveData<>();
        }
        return mWatch;
    }

    public MutableLiveData<List<LockDto>> getLock() {
        if (mLock == null) {
            mLock = new MutableLiveData<>();
        }
        return mLock;
    }

    public MutableLiveData<List<AlertDto>> getAlert() {
        if (mAlert == null) {
            mAlert = new MutableLiveData<>();
        }
        return mAlert;
    }

    public MutableLiveData<List<UnSafeActEventDto>> getUnSafeAct() {
        if (mUnSafeAct == null) {
            mUnSafeAct = new MutableLiveData<>();
        }
        return mUnSafeAct;
    }

    public MutableLiveData<List<ProjectDto>> getProject() {
        if (mProject == null) {
            mProject = new MutableLiveData<>();
            mProject.setValue(new ArrayList<>());
        }
        return mProject;
    }

    public MutableLiveData<List<ShortDto>> getAlertTypes() {
        if (mAlertTypes == null) {
            mAlertTypes = new MutableLiveData<>();
            mAlertTypes.setValue(new ArrayList<>());
        }
        return mAlertTypes;
    }

    public MutableLiveData<AssetDto> getAsset() {
        if (mAsset == null) {
            mAsset = new MutableLiveData<>();
        }
        return mAsset;
    }

    public MutableLiveData<AiDto> getAi() {
        if (mAi == null) {
            mAi = new MutableLiveData<>();
        }
        return mAi;
    }

    public MutableLiveData<HelmetDto> getHelmet() {
        if (mHelmet == null) {
            mHelmet = new MutableLiveData<>();
        }
        return mHelmet;
    }

    public MutableLiveData<MainDto> getAllMainDto() {
        if (allMainDto == null) {
            allMainDto = new MutableLiveData<>();
        }
        return allMainDto;
    }

    public void getData() {
        ThreadManager.getInstance().execute(() -> {
//            List<ProjectDto> projects = mRepository.getProjects();
//            if (projects != null) {
//                OKHttpUtil.getInstance().post(() -> mProject.setValue(projects));
//            }
            LoginDto loginDto = mRepository.getTagByProjId(SPUtil.getInstance().getString(SPName.PROJ_ID));
            if (loginDto != null) {
                OKHttpUtil.getInstance().post(() -> mTagByProj.setValue(loginDto));
            }
            List<ShortDto> alerts = mComboRepository.comboSync("synProjAlarms");
            if (alerts != null) {
                OKHttpUtil.getInstance().post(() -> mAlertTypes.setValue(alerts));
            }
            getMainData();
        });
    }

    public void getProjectList() {
        if (getView() != null) {
            getView().showLoading();
        }
        ThreadManager.getInstance().execute(() -> {
            List<ProjectDto> projects = mRepository.getProjects();
            if (projects != null) {
                OKHttpUtil.getInstance().post(() -> {
                    if (getView() != null) {
                        getView().hideLoading();
                    }
                    mProject.setValue(projects);
                    mResultCode.setValue(ApiStatus.SUCCESS);
                });
            } else {
                OKHttpUtil.getInstance().post(() -> {
                    if (getView() != null) {
                        getView().hideLoading();
                    }
                    mResultCode.setValue(ApiStatus.NET_ERROR);
                });
            }
        });
    }

    public void getAlertList() {
        if (getView() != null) {
            getView().showLoading();
        }
        ThreadManager.getInstance().execute(() -> {
            List<ShortDto> alerts = mComboRepository.comboSync("synProjAlarms");
            if (alerts != null) {
                OKHttpUtil.getInstance().post(() -> {
                    if (getView() != null) {
                        getView().hideLoading();
                    }
                    mAlertTypes.setValue(alerts);
                    mAlertResultCode.setValue(ApiStatus.SUCCESS);
                });
            } else {
                OKHttpUtil.getInstance().post(() -> {
                    if (getView() != null) {
                        getView().hideLoading();
                    }
                    mAlertResultCode.setValue(ApiStatus.NET_ERROR);
                });
            }
        });
    }

    private boolean mIsGetMainData = false;

    public void getMainData() {
        if (mIsGetMainData) {
//            OKHttpUtil.getInstance().post(() -> mRefreshResultCode.setValue(ApiStatus.SUCCESS));
            return;
        }
        mIsGetMainData = true;
        List<ProjectDto> projects = mRepository.getProjects();
        if (projects != null) {
            OKHttpUtil.getInstance().post(() -> mProject.setValue(projects));
        }
        List<String> codes = new ArrayList<>(mTagCodes);
        String projCode = SPUtil.getInstance().getString(SPName.PROJ_CODE);
        for (String code : codes) {
            // 气体可以进行关键字搜索查询
            if (code.equals(TagCode.codeGas)) {
                getGasData(projCode);
                continue;
            }
            // 警报搜索查询
            if (code.equals(TagCode.codeAlert)) {
                getAlert(projCode);
                continue;
            }
            MainDto mainDto = mRepository.getData(projCode, code, "");
            if (mainDto == null) {
                OKHttpUtil.getInstance().post(() -> handleFailStatus(code));
                continue;
            }
            allMainDto.postValue(new MainDto());
            allMainDto.postValue(mainDto);
            switch (code) {
                case TagCode.codePermitToWork:
                    mStatusPTW.postValue(true);
                    mPermitToWork.postValue(new ArrayList<>());
                    mPermitToWork.postValue(mainDto.getDwss());
                    break;
                case TagCode.codeSafetyTraining:
                    mStatusVrs.postValue(true);
                    mVrs.postValue(new ArrayList<>());
                    mVrs.postValue(mainDto.getVr());
                    break;
                case TagCode.codeWatch:
                    mStatusWatch.postValue(true);
                    if (mainDto.getWatch() != null) {
                        handleWatch(mainDto.getWatch().getWatchs());
                    }
                    break;
                case TagCode.codeLock:
                    mStatusLock.postValue(true);
                    handleLock(mainDto.getEleclock());
                    break;
                case TagCode.codeTracking:
                    mStatusAsset.postValue(true);
                    mAsset.postValue(mainDto.getAsset());
                    break;
                case TagCode.code360:
                    mStatusHelmet.postValue(true);
                    mHelmet.postValue(mainDto.getHelmet());
                    break;
                case TagCode.codeUnSafeAct:
                    mStatusUnSafeAct.postValue(true);
                    mUnSafeAct.postValue(new ArrayList<>());
                    if (mainDto.getaIConstSite() != null && mainDto.getaIConstSite().getEvent() != null) {
                        mUnSafeAct.postValue(mainDto.getaIConstSite().getEvent());
                    }
                    break;
                case TagCode.codeAi:
                    mStatusAi.postValue(true);
                    if (mainDto.getAibseg() != null) {
                        mAi.postValue(mainDto.getAibseg());
                    }
                    break;
            }
        }
        List<MapAllDeviceDto> allDeviceDtos = mRepository.allMapDevices(TagCode.allMapTagCode);
        if (allDeviceDtos != null) {
            OKHttpUtil.getInstance().post(() -> mMapDevice.setValue(allDeviceDtos));
        }
        // 获取天气
        MainDto mainDto = mRepository.getData(projCode, TagCode.codeWeather, "");
        if (mainDto != null) {
            OKHttpUtil.getInstance().post(() -> {
                if (mainDto.getWeather() == null) {
                    return;
                }
                mWeather.setValue(new ArrayList<>());
                mWeather.setValue(mainDto.getWeather());
            });
        }
        mIsGetMainData = false;
        OKHttpUtil.getInstance().post(() -> mRefreshResultCode.setValue(ApiStatus.SUCCESS));
    }

    private void handleFailStatus(String code) {
        switch (code) {
            case TagCode.codePermitToWork:
                mStatusPTW.setValue(false);
                break;
            case TagCode.codeSafetyTraining:
                mStatusVrs.setValue(false);
                break;
            case TagCode.codeWatch:
                mStatusWatch.setValue(false);
                break;
            case TagCode.codeLock:
                mStatusLock.setValue(false);
                break;
            case TagCode.codeTracking:
                mStatusAsset.setValue(false);
                break;
            case TagCode.code360:
                mStatusHelmet.setValue(false);
                break;
            case TagCode.codeUnSafeAct:
                mStatusUnSafeAct.setValue(false);
                break;
            case TagCode.codeAlert:
                mStatusAlert.setValue(false);
                break;
            case TagCode.codeAi:
                mStatusAi.setValue(false);
                mAi.setValue(null);
                break;
        }
    }

    private void handleLock(List<LockDto> eleclock) {
        if (eleclock == null) {
            return;
        }
        int size = eleclock.size();
//        for (int i = 0; i < size; i++) {
//            eleclock.get(i).setAddress(getAddressByLatLng(eleclock.get(i).getLat(), eleclock.get(i).getLng()));
//        }
        mLock.postValue(new ArrayList<>());
        mLock.postValue(eleclock);
    }

    private void handleWatch(List<WatchListDto> watch) {
        if (watch == null) {
            return;
        }
        int size = watch.size();
//        for (int i = 0; i < size; i++) {
//            watch.get(i).setAddress(getAddressByLatLng(watch.get(i).getLat(), watch.get(i).getLng()));
//        }
        mWatch.postValue(new ArrayList<>());
        mWatch.postValue(watch);
    }

    private String getAddressByLatLng(double lat, double lng) {
        GoogleMapBean bean = mMapRepository.getAddress(lat, lng, LanguageUtils.getInstance().getMapLanguage());
        if (bean != null && bean.getResults() != null && !bean.getResults().isEmpty()) {
            List<GoogleMapBean.ResultsBean> results = bean.getResults();
            String compoundCode = "";
            if (!results.isEmpty()) {
                compoundCode = bean.getResults().get(0).getFormatted_address();
            }
            if (!TextUtils.isEmpty(compoundCode)) {
                return compoundCode;
            }
        }
        return "";
    }

    public void getGasData(String projCode) {
        MainDto mainDto = mRepository.getData(projCode, TagCode.codeGas, mGasKeyWord);
        OKHttpUtil.getInstance().post(() -> {
            if (mainDto == null) {
                mStatusGas.setValue(false);
                return;
            }
            mStatusGas.setValue(true);
            mGasMonitoring.setValue(new ArrayList<>());
            mGasMonitoring.setValue(mainDto.getEnvtal());
        });
    }

    public void getWatchData(String projCode, String watchKeyWord) {
        MainDto mainDto = mRepository.getData(projCode, TagCode.codeWatch, watchKeyWord);
        OKHttpUtil.getInstance().post(() -> {
            if (mainDto == null) {
                mStatusWatch.setValue(false);
                return;
            }
            allMainDto.postValue(new MainDto());
            allMainDto.postValue(mainDto);
            mStatusWatch.setValue(true);
            mWatch.setValue(new ArrayList<>());
            mWatch.setValue(mainDto.getWatch().getWatchs());
        });
    }

    public void getLockData(String projCode, String lockKeyWord) {
        MainDto mainDto = mRepository.getData(projCode, TagCode.codeLock, lockKeyWord);
        OKHttpUtil.getInstance().post(() -> {
            if (mainDto == null) {
                mStatusLock.setValue(false);
                return;
            }
            allMainDto.postValue(new MainDto());
            allMainDto.postValue(mainDto);
            mStatusLock.setValue(true);
            mLock.setValue(new ArrayList<>());
            mLock.setValue(mainDto.getEleclock());
        });
    }

    public void get360Data(String projCode, String helmetKeyWord) {
        MainDto mainDto = mRepository.getData(projCode, TagCode.code360, helmetKeyWord);
        OKHttpUtil.getInstance().post(() -> {
            if (mainDto == null) {
                mStatusHelmet.setValue(false);
                return;
            }
            allMainDto.postValue(new MainDto());
            allMainDto.postValue(mainDto);
            mStatusHelmet.setValue(true);
            mHelmet.setValue(new HelmetDto());
            mHelmet.setValue(mainDto.getHelmet());
        });
    }

    public void getAlert(String projCode) {
        MainDto mainDto = mRepository.getData(projCode, TagCode.codeAlert, mAlertKeyWord);
        if (mainDto == null) {
            mStatusAlert.postValue(false);
            return;
        }
        mStatusAlert.postValue(true);
        mAlert.postValue(new ArrayList<>());
        if (mainDto.getAlert() != null) {
            mAlert.postValue(mainDto.getAlert());
        }
    }

    public MutableLiveData<MapAllDeviceDto> getMapDeviceDetails() {
        if (mapDeviceDetails == null) {
            mapDeviceDetails = new MutableLiveData<>();
        }
        return mapDeviceDetails;
    }

    public void getDeviceById(String tagCode, String id){
        ThreadManager.getInstance().execute(() -> {
            WatchListDto watchListDto = mRepository.deviceById(tagCode, id);
            if (null == watchListDto || null == watchListDto.getAlertEvent()) return;
            deviceInfo.postValue(new ArrayList<>());
            deviceInfo.postValue(watchListDto.getAlertEvent());
        });
    }
}
